package system

import bus._
import chisel3._
import chisel3.util.experimental.BoringUtils
import common.Constants._
import device._
import yycore.MyCoreConfig


class MySoC() extends Module {
  val io = IO(new Bundle() {
    val interrupt = Input(Bool())
    val master = new ysyxAXI4()//if(!FPGA) {new AXI4()} else{ new ysyxAXI4() }
    val slave = Flipped(new ysyxAXI4())
  })
  io.slave := DontCare//dontTouch(new ysyxAXI4())
  io.interrupt := DontCare

  val tile = Module(new Tile())
  val coh = Module(new Coherence(true))
  //val fakeL2Cache = Module(new FakeL2Cache)
  val clint = Module(new AXI4CLINT(sim = !FPGA))
  val axi4Xbar = Module(new AXI4CrossbarNto1(4))
  val mmioXbar = Module(new CoreLinkIOCrossbar1toN(AddrSpace.mmioAddrSpace))
  val axiBridge = Seq.fill(2)(Module(new AXI_Bridge(nWords)))

  /**
   * connect L1Cache with coherence
   */
  coh.io.in <> tile.io.imem
  coh.io.out.coh <> tile.io.coh
  axiBridge.head.io.in <> coh.io.out.mem
  axiBridge(1).io.in <> tile.io.dmem

  mmioXbar.io.in <> tile.io.dmmio
  val extDev = mmioXbar.io.out(0)
  clint.io.in <> mmioXbar.io.out(1).toAXI4Lite()

  // connect tile to axi, mem, mmio
  axi4Xbar.io.in(0) <> axiBridge.head.io.out
  axi4Xbar.io.in(1) <> tile.io.immio.toAXI4(len = 1)
  axi4Xbar.io.in(2) <> axiBridge(1).io.out
  axi4Xbar.io.in(3) <> extDev.toAXI4(len = 1)

  /**
   * ysyx soc interface
   */
  axi4Xbar.io.out.ar.ready := io.master.arready
  io.master.arvalid := axi4Xbar.io.out.ar.valid
  io.master.araddr := axi4Xbar.io.out.ar.bits.addr
  io.master.arid := axi4Xbar.io.out.ar.bits.id
  io.master.arlen := axi4Xbar.io.out.ar.bits.len
  io.master.arburst := axi4Xbar.io.out.ar.bits.burst
  io.master.arsize := axi4Xbar.io.out.ar.bits.size

  io.master.rready := axi4Xbar.io.out.r.ready
  axi4Xbar.io.out.r.valid := io.master.rvalid
  axi4Xbar.io.out.r.bits.data := io.master.rdata
  axi4Xbar.io.out.r.bits.last := io.master.rlast
  axi4Xbar.io.out.r.bits.id := io.master.rid
  axi4Xbar.io.out.r.bits.resp := io.master.rresp

  axi4Xbar.io.out.aw.ready := io.master.awready
  io.master.awvalid := axi4Xbar.io.out.aw.valid
  io.master.awaddr := axi4Xbar.io.out.aw.bits.addr
  io.master.awid := axi4Xbar.io.out.aw.bits.id
  io.master.awlen := axi4Xbar.io.out.aw.bits.len
  io.master.awburst := axi4Xbar.io.out.aw.bits.burst
  io.master.awsize := axi4Xbar.io.out.aw.bits.size

  axi4Xbar.io.out.w.ready := io.master.wready
  io.master.wvalid := axi4Xbar.io.out.w.valid
  io.master.wdata := axi4Xbar.io.out.w.bits.data
  io.master.wlast := axi4Xbar.io.out.w.bits.last
  io.master.wstrb := axi4Xbar.io.out.w.bits.strb

  io.master.bready := axi4Xbar.io.out.b.ready
  axi4Xbar.io.out.b.valid := io.master.bvalid
  axi4Xbar.io.out.b.bits.id := io.master.bid
  axi4Xbar.io.out.b.bits.resp := io.master.bresp



  val mtipSync = clint.io.extra.get.mtip
  val msipSync = clint.io.extra.get.msip
//    val mtipSync = clint.io.out.mtip
//    val msipSync = clint.io.out.msip
  BoringUtils.addSource(mtipSync, "mtip")
  BoringUtils.addSource(msipSync, "msip")

}




